<template>
    <div class="dv-border-box-8" ref="dom">
      <svg class="dv-border-svg-container" :width="width" :height="height">
        <defs>
          <path
            :id="path"
            :d="pathD"
            fill="transparent"
          />
          <radialGradient
            :id="gradient"
            cx="50%" cy="50%" r="50%"
          >
            <stop
              offset="0%" stop-color="#fff"
              stop-opacity="1"
            />
            <stop
              offset="100%" stop-color="#fff"
              stop-opacity="0"
            />
          </radialGradient>
  
          <mask :id="mask">
            <circle cx="0" cy="0" r="150" :fill="`url(#${gradient})`">
              <animateMotion
                :dur="`${3}s`"
                :path="pathD"
                rotate="auto"
                repeatCount="indefinite"
              />
            </circle>
          </mask>
        </defs>
  
        <polygon fill="transparent" :points="`5, 5 ${width - 5}, 5 ${width - 5} ${height - 5} 5, ${height - 5}`" />
  
        <use
          :stroke="mergedColor[0]"
          stroke-width="1"
          :xlink:href="`#${path}`"
        />
  
        <use
          :stroke="mergedColor[1]"
          stroke-width="3"
          :xlink:href="`#${path}`"
          :mask="`url(#${mask})`"
        >
          <animate
            attributeName="stroke-dasharray"
            :from="`0, ${length}`"
            :to="`${length}, 0`"
            :dur="`${3}s`"
            repeatCount="indefinite"
          />
        </use>
      </svg>
  
      <div class="border-box-content">
        <slot></slot>
      </div>
    </div>
  </template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref, shallowRef } from 'vue';
import { uuid } from '@utils/utils.js'
const id = uuid()
const dom = shallowRef()
const width = ref(0)
const height = ref(0)
const mergedColor = ['#235fa7', '#4fd2dd']
const path = ref(`border-box-8-path-${id}`)
const gradient = ref( `border-box-8-gradient-${id}`)
const mask = ref(`border-box-8-mask-${id}`)

const length = computed(() => {
    return (width.value + height.value - 5) * 2
})
const pathD = computed(() => {
    return `M2.5, 2.5 L${width.value - 2.5}, 2.5 L${width.value - 2.5}, ${height.value - 2.5} L2.5, ${height.value - 2.5} L2.5, 2.5`
})

onMounted(() => {
    nextTick(() => {
        width.value = dom.value.clientWidth 
        height.value = dom.value.clientHeight
    })
})

</script>

<style scoped lang="less">
.dv-border-box-8 {
  position: relative;
  width: 100%;
  height: 100%;

  .dv-border-svg-container {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0px;
    top: 0px;
  }

  .border-box-content {
    position: relative;
    width: 100%;
    height: 100%;
  }
}
</style>
